package logic

import (
	"context"
	"github.com/zeromicro/go-zero/core/collection"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
	"go-zero-real/api/demo/internal/types"
	"log"
	"time"

	"github.com/zeromicro/go-zero/core/logx"
	"go-zero-real/api/demo/internal/svc"
)

type DemoLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewDemoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DemoLogic {

	return &DemoLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *DemoLogic) Demo(req *types.Request) (resp *types.Response, err error) {
	resp = new(types.Response)

	//操作redis
	err = l.svcCtx.RedisModel.Set("aaa", "bbb")
	if err != nil {
		return nil, err
	}

	err = l.startBeginTransaction()
	if err != nil {
		return nil, err
	}

	// 使用数据库连接执行 SQL 操作
	var name string
	err = l.svcCtx.DB.QueryRow(&name, "SELECT username FROM user WHERE id=?", req.Id)
	if err != nil {
		return nil, err
	}
	resp.Message = name

	return resp, nil
}

func (l *DemoLogic) startBeginTransaction() error {

	log.Println(context.Background())

	err := l.svcCtx.DB.TransactCtx(context.Background(), func(ctx context.Context, session sqlx.Session) error {
		// 执行第一条插入语句
		_, err := session.ExecCtx(ctx, "insert into user (id, username) values (?, ?)", 3, "test")
		if err != nil {
			return err // 发生错误，事务会回滚
		}

		// 执行第二条插入语句
		_, err = session.ExecCtx(ctx, "insert into user (id, username) values (?, ?)", 4, "test")
		if err != nil {
			return err // 发生错误，事务会回滚
		}

		// 如果没有错误，返回 nil，事务将提交
		return nil
	})

	if err != nil {
		// 如果事务过程中有错误，返回错误
		return err
	}

	return nil
}

func (l *DemoLogic) getUserInfoCache() {
	cache, err := collection.NewCache(time.Second*2, collection.WithName("any"))
	if err != nil {
		log.Fatal(err)
	}

	v, err := cache.Take("first", func() (interface{}, error) {
		return "first element", nil
	})
	println(v) // output: first element

	cache.Set("first", "first element 2")

	v, err = cache.Take("first", func() (interface{}, error) {
		return "first element", nil
	})
	println(v) // // output: first element 2
}
